package cn.com.acca.ma.dao.impl;

import cn.com.acca.ma.dao.StockMonthDao;
import cn.com.acca.ma.hibernate.util.HibernateUtil;
import cn.com.acca.ma.jpa.util.JpaUtil;
import cn.com.acca.ma.model.ModelStockMonthAnalysis;
import cn.com.acca.ma.model.StockMonth;
import cn.com.acca.ma.model.StockWeek;
import cn.com.acca.ma.mybatis.util.MyBatisUtil;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.Query;

public class StockMonthDaoImpl extends BaseDaoImpl<StockMonthDaoImpl> implements StockMonthDao {

    /**************************************************************************************************
     *
     * 									       更新周线级别，所有月份的股票数据
     *
     **************************************************************************************************/
    /**
     * 计算月线级别，所有股票的基础数据
     */
    @Override
    public void writeStockMonth() {
        sqlSession = MyBatisUtil.openSqlSession();// 打开会话，事务开始;
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonth");
        sqlSession.commit();// 提交会话，即事务提交
        sqlSession.close();// 关闭会话，释放资源
    }

    /**
     * 计算月线级别，所有股票的移动平均线
     */
    @Override
    public void writeStockMonthMA() {
        sqlSession = MyBatisUtil.openSqlSession();// 打开会话，事务开始;
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMA5");
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMA10");
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMA20");
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMA60");
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMA120");
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMA250");
        sqlSession.commit();// 提交会话，即事务提交
        sqlSession.close();// 关闭会话，释放资源
    }

    /**
     * 计算月线级别，所有股票的KD
     */
    @Override
    public void writeStockMonthKD() {
        sqlSession = MyBatisUtil.openSqlSession();// 打开会话，事务开始;
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthKD_init");
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthKD_rsv");
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthKD_k");
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthKD_d");
        sqlSession.commit();// 提交会话，即事务提交
        sqlSession.close();// 关闭会话，释放资源
    }

    /**
     * 计算月线级别，所有股票的MACD
     */
    @Override
    public void writeStockMonthMACD() {
        sqlSession = MyBatisUtil.openSqlSession();// 打开会话，事务开始;
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMACD_init");
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMACD_ema");
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMACD_dif");
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMACD_dea");
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMACD_macd");
        sqlSession.commit();// 提交会话，即事务提交
        sqlSession.close();// 关闭会话，释放资源
    }

    /**************************************************************************************************
     *
     * 									       更新周线级别，某一月的股票数据
     *
     **************************************************************************************************/
    /**
     * 根据开始时间和结束时间，计算某一个月的所有股票的基础数据
     * @param beginDate
     * @param endDate
     */
    @Override
    public void writeStockMonthByDate(String beginDate, String endDate) {
        sqlSession = MyBatisUtil.openSqlSession();// 打开会话，事务开始;
        Map<String, String> map = new HashMap<String, String>();
        map.put("beginDate", beginDate);
        map.put("endDate", endDate);
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthByDate", map);
        sqlSession.commit();// 提交会话，即事务提交
        sqlSession.close();// 关闭会话，释放资源
    }

    /**
     * 根据每个月的开始时间和结束时间，计算某一个月的所有股票的移动平均线
     * @param currentMonthBeginDate
     * @param currentMonthEndDate
     */
    @Override
    public void writeStockMonthMAByDate(String currentMonthBeginDate, String currentMonthEndDate) {
        sqlSession = MyBatisUtil.openSqlSession();// 打开会话，事务开始;
        Map<String, String> map = new HashMap<String, String>();
        map.put("currentMonthBeginDate", currentMonthBeginDate);
        map.put("currentMonthEndDate", currentMonthEndDate);
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMAByDate", map);
        sqlSession.commit();// 提交会话，即事务提交
        sqlSession.close();// 关闭会话，释放资源
    }

    /**
     * 根据开始时间和结束时间，计算某一个月的所有股票的kd
     * @param beginDate
     * @param endDate
     */
    @Override
    public void writeStockMonthKDByDate(String beginDate, String endDate) {
        sqlSession = MyBatisUtil.openSqlSession();// 打开会话，事务开始;
        Map<String, String> map = new HashMap<String, String>();
        map.put("beginDate", beginDate);
        map.put("endDate", endDate);
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthKDByDate_rsv", map);
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthKDByDate_k", map);
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthKDByDate_d", map);
        sqlSession.commit();// 提交会话，即事务提交
        sqlSession.close();// 关闭会话，释放资源
    }

    /**
     * 根据开始时间和结束时间，计算某一个月的所有股票的MACD
     * @param beginDate
     * @param endDate
     */
    @Override
    public void writeStockMonthMACDByDate(String beginDate, String endDate) {
        sqlSession = MyBatisUtil.openSqlSession();// 打开会话，事务开始;
        Map<String, String> map = new HashMap<String, String>();
        map.put("beginDate", beginDate);
        map.put("endDate", endDate);
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMACDByDate_ema", map);
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMACDByDate_dif", map);
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMACDByDate_dea", map);
        sqlSession.insert("cn.com.acca.ma.xmlmapper.StockMonthMapper.writeStockMonthMACDByDate_macd", map);
        sqlSession.commit();// 提交会话，即事务提交
        sqlSession.close();// 关闭会话，释放资源
    }

    /**
     * 根据开始时间beginDate和结束时间endDate，从表STOCK_MONTH中获取END_DATE字段
     * @param beginDate
     * @param endDate
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<Date> getDateByCondition(String beginDate, String endDate){
        logger.info("根据开始时间【" + beginDate + "】和结束时间【" + endDate + "】，"
            + "从表STOCK_MONTH中获取END_DATE字段");

        StringBuffer hql = new StringBuffer("select distinct t.endDate from StockMonth t " +
            "where t.endDate between to_date(?,'yyyy-mm-dd') and to_date(?,'yyyy-mm-dd')");
        session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query query = session.createQuery(hql.toString());
        query.setParameter(0, beginDate);
        query.setParameter(1, endDate);
        List<Date> list = query.list();
        session.getTransaction().commit();
        session.close();

        return list;
    }

    /**
     * 从表STOCK_MONTH中获取date日的所有StockMonth对象
     * @param date
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<StockMonth> getStockMonthByDate(String date){
        logger.info("从表STOCK_MONTH中获取日期【" + date + "】的所有StockMonth对象");

        StringBuffer hql = new StringBuffer("select t from StockMonth t " +
            "where t.endDate=to_date(?,'yyyy-mm-dd') order by t.endDate asc");
        session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query query = session.createQuery(hql.toString());
        query.setParameter(0, date);
        List<StockMonth> list=query.list();
        session.getTransaction().commit();
        session.close();

        return list;
    }

    /**
     * 插入StockMonth对象
     * @param stockMonth
     */
    public void saveStockMonth(StockMonth stockMonth){
        logger.info("插入StockMonth对象");

        em = JpaUtil.currentEntityManager();
        em.getTransaction().begin();
        em.persist(stockMonth);
        em.getTransaction().commit();
        em.close();
    }

    /**************************************************************************************************
     *
     * 									    根据某一月数据更新图表
     *
     **************************************************************************************************/
    /**
     * 根据end_date，查询小于或者等于end_date的end_date
     * @param endDate
     * @return
     */
    @Override
    public String findLessOrEqualByEndDate(String endDate) {
        logger.info("根据end_date【" + endDate + "】，查询上一个end_date");

        StringBuffer hql = new StringBuffer("select to_char(t1.end_date,'yyyy-mm-dd') from (" +
                "select distinct t.end_date from stock_month t where t.end_date<=to_date(?,'yyyy-mm-dd') order by t.end_date desc) t1 " +
                "where rownum<=1");
        session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query query = session.createSQLQuery(hql.toString());
        query.setParameter(0, endDate);
        String _endDate = (String) query.uniqueResult();
        session.getTransaction().commit();
        session.close();

        return _endDate;
    }
}
